package io.renren.modules.iots.test.socket.client;

/**
 * Created by gn on 0029 2015-07-29.
 */


import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;


public class TCPClientReadThread implements Runnable {
    // 监听器，如果缓冲区有数据，通知程序接收
    private Selector selector;
    
    // 定义重试次数
    private int trytimes = 100;
    
    // 服务器是否已经链接
    private boolean connectstatus = false;
    
    // 服务器的ip
    private String serverIP = null;
    
    // 服务器的端口号
    private int serverPORT = 0;
    
    // 客户端的ip
    private String clientIP = null;
    
    // 客户端的端口号
    private int clientPORT = 0;
    
    public TCPClientReadThread(Selector selector,String serverIP,int serverPORT) {
        this.selector = selector;
        this.serverIP = serverIP;
        this.serverPORT = serverPORT;
        new Thread(this).start();
    }

    @Override
    public void run() {
    	System.out.println("我启动了一个读信息的线程");
        try {
            // 轮询访问selector
            while (trytimes >= 0 && trytimes <= 100) { // 在重试次数范围内
            	try {
            		trytimes -- ;// 重试次数递减1
					Thread.sleep(5000); // 线程睡眠，等待5秒
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
                selector.select();//如果队列有新的Channel加入，那么Selector.select()会被唤醒
                // 获得selector中选中的项的迭代器
                Iterator ite = this.selector.selectedKeys().iterator();
                while (ite.hasNext()) {
                    SelectionKey key = (SelectionKey) ite.next();
                    // 删除已选的key,以防重复处理
                    ite.remove();
                    // 连接事件发生
                    if (key.isConnectable()) {
                        SocketChannel channel = (SocketChannel) key.channel();
                        // 如果正在连接，则完成连接
                        if (channel.isConnectionPending()) {
                            channel.finishConnect();
                        }
                        // 设置成非阻塞
                        channel.configureBlocking(false);
                        // 为客户端ip和port赋值
                        clientIP = channel.socket().getInetAddress().getHostAddress();
                        clientPORT = channel.socket().getPort();
                        
                        // 将通道交给SocketUtils.SOCKETMANAGER来管理
                        // key : "clientIP:clientPORT_serverIP:serverPORT"
//                        SocketUtils.SOCKETMANAGER.put(clientIP+":"+clientPORT+"_"+serverIP+":"+serverPORT, channel);
//                        SocketUtils.SOCKETMANAGER.put(serverIP+":"+serverPORT, channel);
                        
                        //在这里可以给服务端发送信息哦
                        channel.write(ByteBuffer.wrap(new String("我们测试中国ab").getBytes()));
                        //在和服务端连接成功之后，为了可以接收到服务端的信息，需要给通道设置读的权限。
                        channel.register(this.selector, SelectionKey.OP_READ );

                    } else if (key.isReadable()) {
                        read(key);
                    }

                }

            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 处理读取服务端发来的信息 的事件
     *
     * @param key
     * @throws IOException
     */
    public void read(SelectionKey key) throws IOException {
        // 服务器可读取消息:得到事件发生的Socket通道
        SocketChannel channel = (SocketChannel) key.channel();
        // 创建读取的缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        channel.read(buffer);
        byte[] data = buffer.array();
        String msg = new String(data).trim();
        System.out.println("服务端收到信息：" + msg);
    }

    public static final String btyetoString(byte[] bArray) {
        StringBuffer sb = new StringBuffer(bArray.length);
        String sTemp;
        for (int i = 0; i < bArray.length; i++) {
            sTemp = Integer.toHexString(0xFF & bArray[i]);
            if (sTemp.length() == 1) {
                sb.append(0);

            }
            sb.append(sTemp.toUpperCase());
            sb.append(" ");
        }
        return sb.toString();
    }
}